﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using CExplorer;
using System.Diagnostics;

namespace PathTransfer
{
    class Program
    {
        #region Dllreference
        [System.Runtime.InteropServices.DllImport("shell32.dll")]
        private static extern int ExtractIconEx(string lpszFile, int niconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, int nIcons);
        #endregion

        static void Main(string[] args)
        {
            List<AppInfo> allAppInfo = XmlHelper._Instance.AllCustomInfo;
            List<string> allFullpath = PathParser._Instance.allPath;
            List<AppInfo> allAppInfoAfterParsed = new List<AppInfo>();

            if (allFullpath == null || allAppInfo == null || allAppInfo.Count == 0 || allFullpath.Count == 0) return;

            //解析
            foreach (AppInfo info in allAppInfo)
            {
                foreach (string fullpath in allFullpath)
                {
                    string exeName = fullpath.Substring(fullpath.LastIndexOf('\\') + 1);
                    if (exeName == info.EXEAppName)
                    {
                        AppInfo inf = new AppInfo(info.CustomAppName, info.EXEAppName, info.IconName, fullpath, info.GroupName, info.Tips, info.MultiVerson, info.Architecture);
                        allAppInfoAfterParsed.Add(inf);     //警告：由于我在AppInfo类中实现了IEquare接口（用customAppName来判定）,所以新加进来的成员不要判断列表中是否已经存在

                    }

                }
            }

            /*
             * System.Diagnostics.FileVersionInfo fvi =
            System.Diagnostics.FileVersionInfo.GetVersionInfo(FilePath);
 
    MessageBox.Show(
        "版本号：" + fvi.FileVersion + "\n" +
        "主要版本号：" + fvi.FileMajorPart + "\n" +
        "次要版本号：" + fvi.FileMinorPart + "\n" +
        "内部版本号：" + fvi.FileBuildPart + "\n" +
        "专用部件号：" + fvi.FilePrivatePart,
        "版本信息", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
             */
            Dictionary<string, FileVersionInfo> versonDic = new Dictionary<string, FileVersionInfo>();

            //version
            foreach (AppInfo appInf in allAppInfoAfterParsed)
            {
                if (!File.Exists(appInf.FullPath)) return;

                FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(appInf.FullPath);

                //给customName加上版本标签(如果本身存在多个版本，但appInf.MultiVerson = false,则默认选择最新版本
                if (appInf.MultiVerson)
                {
                    appInf.CustomAppName = appInf.CustomAppName + "_" + fvi.FileMajorPart.ToString() + "_" + fvi.FileMinorPart.ToString() + "_" + fvi.FileBuildPart.ToString();
                }
                else
                {
                    string tempAppName = appInf.CustomAppName;
                    if (versonDic != null)
                    {
                        if (versonDic.ContainsKey(tempAppName))
                        {
                            if (fvi.FileMajorPart >= versonDic[tempAppName].FileMajorPart   //Main
                                && fvi.FileMinorPart >= versonDic[tempAppName].FileMinorPart    //Mirror
                                && fvi.FileBuildPart >= versonDic[tempAppName].FileBuildPart)   //Build
                            {
                                versonDic[tempAppName] = fvi;
                            }
                        }
                        else
                        {
                            versonDic.Add(tempAppName, fvi);
                        }
                    }
                    
                }
            }

            //Add The Nearst Verson to List
            foreach (AppInfo appInf in allAppInfoAfterParsed)
            {
                if (versonDic.ContainsKey(appInf.CustomAppName))
                {
                    FileVersionInfo temFvi = versonDic[appInf.CustomAppName];
                    appInf.CustomAppName = appInf.CustomAppName + "_" + temFvi.FileMajorPart.ToString() + "_" + temFvi.FileMinorPart.ToString() + "_" + temFvi.FileBuildPart.ToString();
                }
            }

            //arcticture
            foreach (AppInfo appInf in allAppInfoAfterParsed)
            {
                if (!File.Exists(appInf.FullPath)) return;

                //给customName加上架构标签
                if (appInf.Architecture)
                {
                    ushort arc = GetPEArchitecture(appInf.FullPath);
                    if (arc == 0x10b) appInf.CustomAppName = appInf.CustomAppName + "(32bit)";
                    if (arc == 0x20b) appInf.CustomAppName = appInf.CustomAppName + "(64bit)";
                }

            }

            //去重
            List<AppInfo> allAppInfoAfterQuChong = allAppInfoAfterParsed.Distinct<AppInfo>().ToList<AppInfo>();

            //获取应用程序图标并保存
            string path = "";
            try
            {
                foreach (AppInfo appInf in allAppInfoAfterQuChong)
                {
                    System.Drawing.Bitmap bitmap = GetSystemIcon.GetIconByFileName(appInf.FullPath, true).ToBitmap();
                    if (bitmap != null)
                    {
                        if (!Directory.Exists("Images"))
                            Directory.CreateDirectory("Images");

                        path = "Images/" + appInf.CustomAppName + ".png";

                        if (File.Exists(path))
                            File.Delete(path);

                        bitmap.Save(path, System.Drawing.Imaging.ImageFormat.Png);
                    }
                }
            }
            catch
            {
                //什么也不做
            }
            
            //存储
            if (allAppInfoAfterQuChong == null || allAppInfoAfterQuChong.Count == 0) return;
            XmlHelper._Instance.AddXmlNode(allAppInfoAfterQuChong);

            //启动主程序
            if (File.Exists("SoftwareManager.exe"))
                Process.Start("SoftwareManager.exe");
        }

        /// <summary>
        /// 判断程序或dll是x86还是x64(可能返回的两种结果：0x10b - PE32 0x20b - PE32+)
        /// </summary>
        /// <param name="pFilePath"></param>
        /// <returns></returns>
        public static ushort GetPEArchitecture(string pFilePath)
        {
            ushort architecture = 0;
            try
            {
                using (System.IO.FileStream fStream = new System.IO.FileStream(pFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                {
                    using (System.IO.BinaryReader bReader = new System.IO.BinaryReader(fStream))
                    {
                        if (bReader.ReadUInt16() == 23117) //check the MZ signature
                        {
                            fStream.Seek(0x3A, System.IO.SeekOrigin.Current); //seek to e_lfanew.
                            fStream.Seek(bReader.ReadUInt32(), System.IO.SeekOrigin.Begin); //seek to the start of the NT header.
                            if (bReader.ReadUInt32() == 17744) //check the PE\0\0 signature.
                            {
                                fStream.Seek(20, System.IO.SeekOrigin.Current); //seek past the file header,
                                architecture = bReader.ReadUInt16(); //read the magic number of the optional header.
                            }
                        }
                    }
                }
            }
            catch (Exception) { /* TODO: Any exception handling you want to do, personally I just take 0 as a sign of failure */}
            //if architecture returns 0, there has been an error.
            return architecture;
        }

        //private static void SavePic(AppInfo inf)
        //{

        //    IntPtr[] largeIcons, smallIcons;  //存放大/小图标的指针数组

        //    string appPath = inf.FullPath;

        //    //第一步：获取程序中的图标数

        //    int IconCount = ExtractIconEx(appPath, -1, null, null, 0);

        //    //第二步：创建存放大/小图标的空间

        //    largeIcons = new IntPtr[IconCount];
        //    smallIcons = new IntPtr[IconCount];

        //    //第三步：抽取所有的大小图标保存到largeIcons和smallIcons中

        //    ExtractIconEx(appPath, 0, largeIcons, smallIcons, IconCount);

        //    //第四步：显示抽取的图标(推荐使用imageList和listview搭配显示）

        //    ImageList imgList= new ImageList();
        //    for (int i = 0; i < IconCount; i++)
        //    {
        //        //imgList.Images.Add(Icon.FromHandle(largeIcons[i])); //图标添加进imageList中
        //    }
        //    //第五步：保存图标

        //    for (int i = 0; i < imgList.Images.Count; i++)
        //    {
        //        System.IO.FileStream fs = new System.IO.FileStream(Application.StartupPath + "\\newIcon.png", System.IO.FileMode.Create);
        //        imgList.Images[i].

        //        //this.imageList1.Images[this.listview1.Items[i].ImageIndex].Save(fs, System.Drawing.Imaging.ImageFormat.Png);

        //        fs.Close();
        //    }  
        //}

        // 一般为LR_DEFAULTCOLOR | LR_CREATEDIBSECTION
    }
}
